package com.dosgi.kit;

import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 锁工具类
 * 
 * @author dingnate
 *
 */
public class LockKit {
	private static final String LOCKCONDITION_SEPARATOR = "--";
	private final static ConcurrentHashMap<String, ReentrantLock> LockMap = new ConcurrentHashMap<String, ReentrantLock>();
	private final static ConcurrentHashMap<String, Condition> condtionMap = new ConcurrentHashMap<String, Condition>();
	private final static String CONDTION_DEFAULT_NAME = "CONDTION_DEFAULT_NAME";

	LockKit() {
	}

	/**
	 * @param name
	 *            锁的名字 不能为null
	 * @return
	 */
	public static ReentrantLock getLock(String name) {
		ReentrantLock lock = LockMap.get(name);
		if (lock != null)
			return lock;
		ReentrantLock newLock = new ReentrantLock();
		lock = LockMap.putIfAbsent(name, newLock);
		if (lock == null)
			lock = newLock;
		return lock;
	}

	/**
	 * 获取lockName锁的默认Condition
	 * 
	 * @param lockName
	 * @return
	 */
	public static Condition getCondition(String lockName) {
		return getCondition(lockName, CONDTION_DEFAULT_NAME);
	}

	/**
	 * 获取lockName锁的condtionName的Condition
	 * 
	 * @param lockName
	 * @param condtionName
	 * @return
	 */
	public static Condition getCondition(String lockName, String condtionName) {
		String condtionKey = getCondtionKey(lockName, condtionName);
		Condition condition = condtionMap.get(condtionKey);
		if (condition != null)
			return condition;
		Condition newCondition = getLock(lockName).newCondition();
		condition = condtionMap.putIfAbsent(condtionKey, newCondition);
		if (condition == null)
			condition = newCondition;
		return condition;
	}

	private static String getCondtionKey(String lockName, String condtionName) {
		return new StringBuilder(lockName).append(LOCKCONDITION_SEPARATOR)
				.append(condtionName).toString();
	}

	/**
	 * @param name
	 * @return
	 * @throws InterruptedException
	 */
	public static ReentrantLock lock(String name) {
		ReentrantLock lock = getLock(name);
		lock.lock();
		return lock;
	}
	
	public static void destoryLock(String name) {
		LockMap.remove(name);
		String condtionKeyPrefix = getCondtionKey(name, "");
		Iterator<Entry<String, Condition>> iterator = condtionMap.entrySet().iterator();
		while (iterator.hasNext()) {
			if (iterator.next().getKey().startsWith(condtionKeyPrefix))
				iterator.remove();
		}
	}
}
